package com.um2.mauction.session.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.ejb.Timeout;
import javax.ejb.Timer;
import javax.ejb.TimerService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import com.um2.mauction.entity.Enchere;
import com.um2.mauction.entity.Produit;
import com.um2.mauction.entity.Utilisateur;
import com.um2.mauction.entity.Vente;
import com.um2.mauction.session.remote.VenteManagerRemote;

@Remote(VenteManagerRemote.class)
@Stateless
public class VenteManagerBean implements VenteManagerRemote {
	
	public static final String RemoteJNDIName = VenteManagerBean.class.getSimpleName() + "/remote";

	@PersistenceContext
	private EntityManager em;

	// TIMER
	@Resource
	TimerService timerService;

	public void addTimerToSale(Vente sale, Date expiration) {
		timerService.createTimer(expiration, sale);
	}

	@Timeout
	public void monitorSale(Timer timer) {
		Vente sale = (Vente) timer.getInfo();
		this.finaliserVente(sale.getSale_id());

	}

	/**
	 * Retourne la vente a partir de son identifiant
	 */
	public Vente getVente(int idSale) {
		return em.find(Vente.class, idSale);
	}

	/**
	 * Ajoute une vente
	 */
	public int addVente(float montantInitial, float montantReserve,String dateDebut, double duree, int etat, Utilisateur seller,
			Produit item) {
		Vente v = new Vente(montantInitial, montantReserve, dateDebut, duree,
				etat, seller, item);
		
		//Date d = new Date();
		//addTimerToSale(v, d);
						
		em.persist(v);
		return v.getSale_id();
	}
	
	public int addVente(Vente v){
		em.persist(v);
		return v.getSale_id();
	}

	/**
	 * Met a jour une vente
	 */
	public void updateVente(int idSale, float montantInitial,
			float montantReserve, String dateDebut, double duree, int etat,
			Utilisateur seller, Produit item) {
		Vente v = em.find(Vente.class, idSale);
		v.setMontantInitial(montantInitial);
		v.setMontantReserve(montantReserve);
		v.setDateDebut(dateDebut);
		v.setDuree(duree);
		v.setEtat(etat);
		v.setSeller(seller);
		v.setItem(item);
	}

	/**
	 * Supprime une vente
	 */
	public void deleteVente(int idSale) {
		Vente v = em.find(Vente.class, idSale);
		em.remove(v);
	}

	/**
	 * Retourne la liste de toutes les ventes
	 */
	@SuppressWarnings("unchecked")
	public List getAllVentes() {
		Query query = em.createQuery("SELECT v " + "FROM Vente v ");

		// Get ventes
		List<Vente> ventes = query.getResultList();
		return ventes;
	}

	/**
	 * Ajoute une enchere existante a une vente existante
	 * 
	 * @param idBid
	 * @param idSale
	 */
	public void addEnchereToVente(int idBid, int idSale) {
		Enchere e = em.find(Enchere.class, idBid);
		Vente v = em.find(Vente.class, idSale);
		v.assignEnchere(e);
	}

	/**
	 * Retoune la derniere enchere d'une vente
	 * 
	 * @param idSale
	 */
	public Enchere getLastEnchereOfVente(int idSale) {
	Vente v = em.find(Vente.class, idSale);		
	Set<Enchere> bids = v.getBids();
	Iterator<Enchere> iter = bids.iterator();
	Enchere e =null;
			while (iter.hasNext()) {
		 e = iter.next();
		 System.out.println(e.getAmount()+"|");
		 }
	 return e;
	}

	private void finaliserVente(int idSale) {
		//Enchere bid_winner = this.getLastEnchereOfVente(idSale);

		// "désactiver" la vente
		// proposer un lien à l'utilisateur pour lancer le processus (+envoi
		// message)
		// de commande (via le stateful bean)

		// OrderBean o = new OrderBean();

	}

	/**
	 * Retourne la liste des ventes d'une categorie
	 */
	@SuppressWarnings("unchecked")
	public List getAllVentesOfCategory(int idCategory)
	{
		List<Vente> ventesCat = new ArrayList<Vente>();
		Query query = em.createQuery("SELECT v " + "FROM Vente v ");

		// Get ventes
		List<Vente> ventes = query.getResultList();
		for(int i=0;i<ventes.size();i++)
		{
			Vente v = ventes.get(i);
			if(v.getItem().getCategorie().getIdCategorie() == idCategory)
			{
				ventesCat.add(v);
			}
		}
		return ventesCat;
	}

	public void mergeVente(Vente v) {
		em.merge(v);
		
	}	
}